| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061 |
- 'use client';
- import { Area, AreaChart, ResponsiveContainer, Tooltip, XAxis, YAxis } from 'recharts';
- import type { StockPriceRow } from '@/types/stock';
- import { changeDirection, formatNumber } from '@/lib/utils/stock';
- // recharts(d3 포함) 실제 렌더 본체 — StockPriceChart 가 next/dynamic({ssr:false})로 지연 로드.
- // 색은 래퍼 dir 클래스(.stock-chart--up/down/flat)의 CSS color 를 currentColor 로 상속
- // (recharts stroke/fill 은 SVG presentation attribute 라 var() 미해석 → currentColor 사용).
- type Props = {
- // GetDetail.recentPrices — 최신순(newest-first). 호출부에서 length>=2 보장.
- prices: StockPriceRow[];
- name: string;
- };
- export default function PriceChartInner({ prices, name }: Props)
- {
- // 과거→최신 순서로 뒤집어 종가 시계열 구성
- const series = [...prices].reverse().map(p => ({ date: p.tradingDate, close: p.close }));
- const dir = changeDirection(series[series.length - 1].close - series[0].close);
- return (
- <figure className={`stock-chart stock-chart--${dir}`}>
- <figcaption className='stock-chart__caption'>최근 {series.length}일 종가 추이</figcaption>
- <div className='stock-chart__canvas' aria-label={`${name} 최근 ${series.length}일 종가 추이 그래프`} role='img'>
- <ResponsiveContainer width='100%' height='100%'>
- <AreaChart data={series} margin={{ top: 8, right: 8, bottom: 0, left: 0 }}>
- <XAxis dataKey='date' hide />
- <YAxis hide domain={['dataMin', 'dataMax']} />
- <Tooltip
- cursor={{ stroke: 'currentColor', strokeOpacity: 0.3 }}
- contentStyle={{
- background: 'var(--bg-elevated)',
- border: '1px solid var(--border-default)',
- borderRadius: 0,
- fontSize: 'var(--fs-xs)',
- color: 'var(--text-primary)'
- }}
- labelStyle={{ color: 'var(--text-muted)' }}
- formatter={(value) => {
- const n = Array.isArray(value) ? Number(value[0]) : Number(value);
- return [formatNumber(Number.isFinite(n) ? n : null), '종가'];
- }}
- labelFormatter={(label) => String(label)}
- />
- <Area
- type='monotone'
- dataKey='close'
- stroke='currentColor'
- strokeWidth={2}
- fill='currentColor'
- fillOpacity={0.1}
- dot={false}
- isAnimationActive={false}
- />
- </AreaChart>
- </ResponsiveContainer>
- </div>
- </figure>
- );
- }
|